package com.lx.aop;

import com.alibaba.fastjson.JSON;
import com.lx.annotation.AnoDot;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * 注解拦截器
 *
 * @author 段誉
 * @create 2019-03-11 15:04
 */
@Aspect
@Component
public class AnoAspect {
  /**
   * 配置对所有controller方法的拦截器
   */
  @Before("execution(public * com.lx.controller.*.*(*))")
  public void doBefore() {
    System.out.println("进入controller方法before拦截器");
  }

  /**
   * 定义拦有controller方法的截器切入点
   */
  @Pointcut("execution(public * com.lx.controller.*.*(*))")
  public void point() {
  }

  /**
   * 在方法执行之后执行
   */
  @After("point()")
  public void doAfter(JoinPoint joinPoint) {
    //getArgs返回且入点的所有参数
    System.out.println("进入controller方法after拦截器:" + JSON.toJSONString(joinPoint.getArgs()));
  }

  /**
   * 方法执行完毕后，通过args指定参数，通过returning指定返回的结果，要求返回值类型匹配
   * @param num
   * @param result
   */
  @AfterReturning(value = "point() && args(num)", returning = "result")
  public void doAfterReturning(Integer num, String result) {
    System.out.println("在方法执行完返回之后执行AfterReturning拦截器!num:" + num + ",result:" + result);
  }

  @Before("point()")
  public void doPointBefore() {
    System.out.println("通过切入点的方式进入before拦截器");
  }
  /**
   * 环绕执行拦截器
   * @param joinPoint
   */
  @Around("point()")
  public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
    System.out.println("执行环绕Around拦截器before");
    Object result = joinPoint.proceed();
    System.out.println("执行环绕Around拦截器after");
    return result;
  }



  /**
   * 使用注解拦截器
   * @param anoDot 注解
   */
  @Before("@annotation(anoDot)")
  public void anoBefore(AnoDot anoDot) {
    System.out.println("执行了AnoSpect注解before拦截器");
  }

}
